package inet

import (
	"time"

	"gitee.com/hasika/gotool/container"
)

type Session struct {
	connections container.MapInterface[ConnectionType, PublicConn]
	expireTime  time.Time
	Uid         uint64
	Ctx         container.MapInterface[string, any]
}

func (s *Session) KeepAlive() {
	s.expireTime = time.Now().Add(time.Second * 20)
}

func (s *Session) GetExpireTime() time.Time {
	return s.expireTime
}

func (s *Session) GetConnections() []PublicConn {
	var connections []PublicConn = nil
	s.connections.Range(func(key ConnectionType, value PublicConn) (shouldContinue bool) {
		connections = append(connections, value)
		return true
	})
	return connections
}

func (s *Session) AddConnection(conn PublicConn) {
	conn.SetSession(s)
	oldConn, _ := s.connections.Swap(conn.GetConnectionType(), conn)
	if oldConn != nil {
		Log.Warnf("replace one connection of the kind %+v is here,close old connection %+v", conn.GetConnectionType(), oldConn.GetRemote())
		oldConn.CloseConnectionAllCallback("new connection replaced")
	}
}

func (s *Session) RemoveConnection(conn PublicConn, reason string) {
	s.connections.CompareAndDelete(conn.GetConnectionType(), conn)
	conn.CloseConnectionAllCallback(reason)
}

func (s *Session) GetConnectionByType(connectionType ConnectionType) PublicConn {
	v, ok := s.connections.Load(connectionType)
	if ok {
		return v
	}
	return nil
}

func NewSession(uid uint64) *Session {
	return &Session{Uid: uid, connections: container.NewSyncMap[ConnectionType, PublicConn](), expireTime: time.Now().Add(time.Second * 10), Ctx: container.NewSyncMap[string, any]()}
}
